package libra.sentinelTest.controller;

import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;

/**
 * Sentinel - ParamKey热点参数流控测试Controller
 * !!!：
 * 	热点key限流对默认的SpringMVC资源无效(即Sentinel通过对SpringMVC的@RequestMapping解析创建的默认URL资源无效)；
 * 	只有通过@SentinelResource注解标注的自定义资源才能使用热点key限流
 */
@RestController
@RequestMapping("paramflow")
public class ParamFlowController {
	String from = getClass().getSimpleName();
	@Autowired
	ApplicationContext ac;
	
	// @SentinelResource的blockExec函数，原方法调用被限流/降级/系统保护的时候调用
	public Object testHotKey_BlockExec(String key_1, String key_2, String key_3, HttpServletResponse resp, BlockException ex) {
		resp.setStatus(429);
		return Map.of("from", from, "method", "testHotKey_BlockExec");
	}
	/************************** 热点参数测试 ******************************/
	/**
	 * 测试一、不使用@SentinelResource注解定义资源，使用Sentinel解析@RequestMapping的默认资源进行热点key测试
	 */
	@RequestMapping("testUnSentinelResource")
	public Object testUnSentinelResource( String key_1, String key_2, String key_3, HttpServletResponse resp ) throws Exception {
		return Map.of("from", from, "method", "testUnSentinelResource", "key", 
				Map.of("key_1",StringUtils.hasText(key_1)?key_1:"",
						"key_2",StringUtils.hasText(key_2)?key_2:"",
						"key_3",StringUtils.hasText(key_3)?key_3:""));
	}
	
	
	/**
	 * 测试二、使用@SentinelResource注解定义资源进行热点key测试
	 */
	//方式一、在Controller通过@SentinelResource直接定义资源
	@RequestMapping("testHotKeyByReq")
	@SentinelResource(value = "testHotKeyByReq", blockHandler = "testHotKey_BlockExec" )
	public Object testHotKeyByReq( String key_1, String key_2, String key_3, HttpServletResponse resp ) throws Exception {
		return Map.of("from", from, "method", "testHotKeyByReq", "key", 
				Map.of("key_1",StringUtils.hasText(key_1)?key_1:"",
						"key_2",StringUtils.hasText(key_2)?key_2:"",
						"key_3",StringUtils.hasText(key_3)?key_3:""));
	}
	
	//方式二、在Controller调用的资源方法通过@SentinelResource定义资源
	@RequestMapping("testHotKeyByMethod")
	public Object testHotKeyByMethod( String key_1, String key_2, String key_3, HttpServletResponse resp ) throws Exception {
		Object testHotKeyByMethodCall = ac.getBean(getClass()).testHotKeyByMethodCall( key_1, key_2, key_3, resp);
		return testHotKeyByMethodCall;
	}
	@SentinelResource(value = "testHotKeyByMethod", blockHandler = "testHotKey_BlockExec" )
	public Object testHotKeyByMethodCall( String key_1, String key_2, String key_3, HttpServletResponse resp ) throws Exception {
		return Map.of("from", from, "method", "testHotKeyByMethod", "key", 
				Map.of("key_1",StringUtils.hasText(key_1)?key_1:"",
						"key_2",StringUtils.hasText(key_2)?key_2:"",
						"key_3",StringUtils.hasText(key_3)?key_3:""));
	}
	
	
	
	
	
	
	
	/************************** 热点参数高阶应用测试[参数例外项] ******************************/
	// 测试'热点key.参数例外项'
	@RequestMapping("testHotKeyWithParamOption")
	@SentinelResource(value = "testHotKeyWithParamOption", blockHandler = "testHotKey_BlockExec" )
	public Object testHotKeyWithParamOption( String key_1, String key_2, String key_3, HttpServletResponse resp ) throws Exception {
		return Map.of("from", from, "method", "testHotKeyWithParamOption", "key", 
				Map.of("key_1",StringUtils.hasText(key_1)?key_1:"",
						"key_2",StringUtils.hasText(key_2)?key_2:"",
						"key_3",StringUtils.hasText(key_3)?key_3:""));
	}
}
